package cn.dengta.webapp.trade.entity.meta;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

import cn.dengta.common.model.SwitchSupport;
import cn.dengta.webapp.trade.entity.meta.MetaConfig.MetaRuleConfig;
import cn.dengta.webapp.user.model.ActivityStatusDescriptor;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Getter;
import lombok.Setter;
import me.codeplayer.util.*;

/**
 * 充值全额返的规则配置对象
 */
@Getter
@Setter
public class DoubleGiveRechargeRule implements MetaRuleConfig {

	/** 活动开始时间 */
	private Date beginTime;
	/** 活动结束时间 */
	private Date endTime;
	/** 限制参加次数 */
	private Integer limitTimes;
	/** 充值全额返配置 */
	public DoubleGiveRechargeEntry[] entries;
	private transient ActivityStatusDescriptor statusDescriptor;

	@Override
	public void validate() {
		final DoubleGiveRechargeEntry[] entries = this.entries;
		EasyDate d = new EasyDate(beginTime);
		beginTime = d.beginOf(Calendar.DAY_OF_MONTH).toDate();
		endTime = d.setDate(endTime).endOf(Calendar.DAY_OF_MONTH).toDate();
		Assert.isTrue(endTime.getTime() > beginTime.getTime(), "结束时间必须大于开始时间！");
		Assert.isTrue(X.size(entries) > 0, "充值全额返奖励配置不能为空！");
		Assert.isTrue(limitTimes > 0, "允许参加次数必须大于0！");
		Assert.isTrue(entries[0].getDay() == 1, "领取天数必须从1开始");
		for (int i = entries.length - 1; i > 0; ) {
			DoubleGiveRechargeEntry entry = entries[i--];
			entry.validate();
			DoubleGiveRechargeEntry nextEntry = entries[i];
			nextEntry.validate();
			Assert.isTrue(entry.day > nextEntry.day, "领取天数只能递增！");
			Assert.isTrue((entry.day - nextEntry.day) == 1, "领取天数只能递增 1");
		}
		final BigDecimal totalRate = Arrays.stream(entries).map(DoubleGiveRechargeEntry::getAwardRate).reduce(BigDecimal.ZERO, BigDecimal::add);
		Assert.isTrue(totalRate.compareTo(Arith.HUNDRED) == 0, "返还比例总和必须 等于 100!");
	}

	@JSONField(serialize = false)
	public BigDecimal getTotalRate() {
		return Arrays.stream(entries).map(DoubleGiveRechargeEntry::getAwardRate).reduce(BigDecimal.ZERO, BigDecimal::add);
	}

	@Override
	public void init(MetaRuleConfig config) {
		DoubleGiveRechargeRule rule = (DoubleGiveRechargeRule) config;
		this.beginTime = rule.beginTime;
		this.endTime = rule.endTime;
		this.limitTimes = rule.limitTimes;
		this.entries = rule.entries;
	}

	@JSONField(serialize = false)
	public DoubleGiveRechargeEntry getEntry(Integer times, boolean defaultValue) {
		final DoubleGiveRechargeEntry[] entries = this.entries;
		DoubleGiveRechargeEntry entry;
		for (int i = entries.length - 1; i >= 0; i--) {
			entry = entries[i];
			if (times >= entry.getDay()) {
				return entry;
			}
		}
		return defaultValue ? entries[0] : null;
	}

	@JSONField(serialize = false)
	public ActivityStatusDescriptor getStatusDescriptor(final long baseTime) {
		ActivityStatusDescriptor descriptor = statusDescriptor;
		if (descriptor == null) {
			descriptor = ActivityStatusDescriptor.of(SwitchSupport.statusValue(baseTime, beginTime.getTime(), endTime));
			statusDescriptor = descriptor;
		}
		return descriptor;
	}

	public boolean isActivity(long now) {
		return SwitchSupport.between(now, beginTime, endTime);
	}

	/**
	 * 充值全额返规则实体
	 */
	@Setter
	@Getter
	public static class DoubleGiveRechargeEntry implements Serializable {

		/** 领取天数 */
		protected Integer day;
		/** 奖励比例% */
		protected BigDecimal awardRate;

		public DoubleGiveRechargeEntry() {
		}

		public DoubleGiveRechargeEntry(Integer day, BigDecimal awardRate) {
			this.day = day;
			this.awardRate = awardRate;
		}

		public void validate() {
			Assert.isTrue(day > 0, "返还天数不能小于0！");
			Assert.isTrue(awardRate.compareTo(BigDecimal.ZERO) > 0, "返还奖励必须大于0！");
		}

	}

}
